﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace System.Reactive.Concurrency
{
	[ContractClass(typeof(VirtualTimeSchedulerBaseContract<,>))]
	public abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> : IScheduler
	{
		protected IComparer<TAbsolute> Comparer
		{
			get
			{
				Contract.Ensures(Contract.Result<IComparer<TAbsolute>>() != null, null, "Contract.Result<IComparer<TAbsolute>>() != null");
				return null;
			}
		}

		public DateTimeOffset Now
		{
			get
			{
				return default(DateTimeOffset);
			}
		}

		protected VirtualTimeSchedulerBase(TAbsolute initialClock, IComparer<TAbsolute> comparer)
		{
			Contract.Requires(comparer != null, null, "comparer != null");
		}

		public abstract IDisposable ScheduleAbsolute<TState>(TState state, TAbsolute dueTime, Func<IScheduler, TState, IDisposable> action);

		public IDisposable ScheduleRelative<TState>(TState state, TRelative dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		#region IScheduler Members
		public IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
		{
			return null;
		}

		public IDisposable Schedule<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			return null;
		}

		public IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			return null;
		}
		#endregion
	}

	[ContractClassFor(typeof(VirtualTimeSchedulerBase<,>))]
	internal abstract class VirtualTimeSchedulerBaseContract<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative>
	{
		public VirtualTimeSchedulerBaseContract()
			: base(default(TAbsolute), null)
		{
		}

		public override IDisposable ScheduleAbsolute<TState>(TState state, TAbsolute dueTime, Func<IScheduler, TState, IDisposable> action)
		{
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}
	}
}